﻿namespace DesignModeConsole.行为型.解释器模式.告警规则进阶;

/// <summary>
/// 告警规则解释器
/// </summary>
public class AlertRuleInterpreter2 : IAlertRuleExpression2
{
    private IAlertRuleExpression2 _alertRuleExpression;

    public AlertRuleInterpreter2(string ruleExpression)
    {
        var strArray = ruleExpression.Split(" ");
        HandlerExpression(strArray);
    }

    public AlertRuleInterpreter2(IEnumerable<string> param)
    {
        var strArray = string.Join(" ", param).Split(" ");
        HandlerExpression(strArray);
    }

    public bool Interpret(Dictionary<string, long> statusDic)
    {
        return _alertRuleExpression.Interpret(statusDic);
    }

    private void HandlerExpression(IReadOnlyList<string> strArray)
    {
        /*
         处理逻辑：循环根据空格分割后的内容，然后取到第一组，然后处理
        将另外的那部分继续循环按照第一组的方式处理
         */

        // 括号的数量
        var bracketNum = 0;
        //是否是通过and连接操作
        var isAndConnector = false;

        // 这一组表达式是否结束
        var isOver = false;

        // 左侧集合
        var leftList = new List<string>();
        var i = 0;
        for (; i < strArray.Count; i++)
        {
            var curr = strArray[i];
            if (curr is " ")
                continue;

            switch (curr)
            {
                case "(":
                    if (bracketNum > 0)
                    {
                        leftList.Add(curr);
                    }
                    bracketNum++;
                    break;

                case ")":
                    // 如果括号的数量大于1 那么就拼接当前的节点，并且标注括号数量减一
                    if (bracketNum > 1)
                    {
                        leftList.Add(curr);
                    }
                    bracketNum--;
                    break;

                case "&&":

                    // 如果没有组，那么就设置存在and连接，当前表达式结束
                    if (bracketNum == 0)
                    {
                        isAndConnector = true;
                        isOver = true;
                    }
                    else
                    {
                        leftList.Add(curr);
                    }
                    break;

                case "||":

                    // 如果没有组，那么就设置没有and连接，然后当前表达式结束
                    if (bracketNum == 0)
                    {
                        isAndConnector = false;
                        isOver = true;
                    }
                    else
                    {
                        leftList.Add(curr);
                    }
                    break;

                default:
                    leftList.Add(curr);
                    break;
            }

            // 如果这一组结束
            if (isOver)
            {
                i++;
                break;
            }
        }

        var rightList = strArray.Skip(i).Take(strArray.Count - 1).ToList();
        if (rightList.Count == 0)
        {
            // 如果左侧内容只有三个，那么就当成一个表达式去处理，否则再次进行规则解析处理
            _alertRuleExpression = leftList.Count == 3 ? new AndExpression2(leftList)
                : new AlertRuleInterpreter2(leftList);
        }
        else
        {
            var list3 = new List<IAlertRuleExpression2>();
            //如果左侧只有三个 那么就当成一组去拼接
            if (leftList.Count == 3)
            {
                list3.Add(new AndExpression2(leftList));
            }
            else
            {
                list3.Add(new AlertRuleInterpreter2(leftList));
            }

            // 右侧和上面同理
            if (rightList.Count == 3)
            {
                list3.Add(new AndExpression2(rightList));
            }
            else
            {
                list3.Add(new AlertRuleInterpreter2(rightList));
            }
            _alertRuleExpression = isAndConnector ? new AndExpression2(list3) : new OrExpression(list3);
        }
    }
}